/**
 * <label id="preview" class="preview">
 *     +
 *     <input type="file" name="thumb" id="thumb" />
 * </label>
 *
 * <style type="text/css">
 *     label.preview{
 *         width: 200px;
 *         height: 200px;
 *         line-height: 200px;
 *         text-align: center;
 *         border: 1px dashed #ccc;
 *         border-radius: 3px;
 *         font-size: 30px;
 *         color: #666;
 *         padding: 0;
 *         background-size: cover;
 *         background-position: center;
 *         position: relative;
 *     }
 *     label.preview input{
 *         display: none;
 *     }
 * </style>
 * <script type="text/javascript">
 *     $(function () {
 *         var uploader = $("#thumb").uploadImagePreview({
 *             destID: 'preview', // 展示预览图片的元素，div、label等
 *             imgUrl: 'default image url', // 默认显示的图片
 *             server: "", // 上传服务器地址
 *             autoUpload: true, // 是否自动上传，需要填写server参数
 *             hoverPreview: false, // 鼠标悬浮是否展示预览
 *             hoverPreviewWidth: "300px", // 鼠标悬浮预览图片大小
 *             change: null, // 回调事件，回传参数为图片数据
 *             startUpload: null, // 开始上传回调
 *             finishUpload: null, // 完成上传回调
 *         });
 *
 *         // 单独调用上传方法
 *         uploader.upload(function(ret) {
 *             // ret 是服务器返回数据
 *         });
 *
 *         // 支持同步调用
 *         var ret = await uploader.upload(); // ret 是服务器返回数据
 *     });
 * </script>
 */
(function ($) {
    
    var uploadImagePreview = function ($this, options) {
        
        var self = this;
        
        var defaults = {
            destID: "", // 展示预览图片的元素，div、label等
            imgUrl: "", // 默认显示的图片
            server: "", // 上传服务器地址
            autoUpload: true, // 是否自动上传，需要填写server参数
            hoverPreview: false, // 鼠标悬浮是否展示预览
            hoverPreviewWidth: "300px", // 鼠标悬浮预览图片大小
            change: null, // 回调事件，回传参数为图片数据
            startUpload: null, // 开始上传回调
            finishUpload: null, // 完成上传回调
        };
        
        options = $.extend({}, defaults, options);
        
        if (options.imgUrl) {
            $("#" + options.destID).data('bg', options.imgUrl);
            $("#" + options.destID).css('backgroundImage', 'url(' + options.imgUrl + ')');
        }
        
        if (options.hoverPreview) {
            $("#" + options.destID).hover(function () {
                if ($(this).data('bg')) {
                    $(this).append("<p id='preview_" + options.destID + "' style='position:fixed;z-index:99999;'><img style='max-width: " + options.hoverPreviewWidth + "' src='" + $(this).data('bg') + "'></p>");
                    $(this).mousemove(function (e) {
                        $("#preview_" + options.destID).css({
                            "top": (e.clientY + 10) + "px",
                            "left": (e.clientX + 20) + "px"
                        }).fadeIn("fast");
                    });
                }
            }, function () {
                $("#preview_" + options.destID).remove();
            });
        }
        
        // 显示清空按钮
        $("#" + options.destID).append("<div id='close_" + options.destID + "' style='position:absolute;z-index:99999;top:0;right:0;height:20px;width:20px;text-align:center;font-size:13px;line-height:20px;color:#fff;background:rgba(255,0,0,0.8);cursor: pointer;display:none;'>X</div>");
        $("#close_" + options.destID).click(function(e) {
            e.preventDefault();
            e.stopPropagation();
            $this.html($this.html());
            $("#" + options.destID).data('bg', '');
            $("#" + options.destID).css('backgroundImage', "none");
            options.change && options.change(''); // 清空
            $("#close_" + options.destID).fadeOut("fast");
        });
        $("#" + options.destID).hover(function () {
            if ($(this).data('bg') && $(this).data('bg') != '') {
                $("#close_" + options.destID).fadeIn("fast");
            }
        }, function () {
            $("#close_" + options.destID).fadeOut("fast");
        });
        
        $this.change(function () {
            var regex = /(.*)\.(jpg|jpeg|gif|bmp|png)$/i;
            var val = $this.val();
            if (!regex.test(val)) {
                alert("请选择图片");
                return false;
            }
            
            if (window.FileReader) {
                HanderFileReader($this);
            } else {
                $("#" + options.destID).html("浏览器不支持预览图片");
            }
        });
        
        var base64;
        
        function HanderFileReader($this) {
            var oFReader = new window.FileReader();
            var rFilter = /^(?:image\/bmp|image\/cis\-cod|image\/gif|image\/ief|image\/jpeg|image\/jpeg|image\/jpeg|image\/pipeg|image\/png|image\/svg\+xml|image\/tiff|image\/x\-cmu\-raster|image\/x\-cmx|image\/x\-icon|image\/x\-portable\-anymap|image\/x\-portable\-bitmap|image\/x\-portable\-graymap|image\/x\-portable\-pixmap|image\/x\-rgb|image\/x\-xbitmap|image\/x\-xpixmap|image\/x\-xwindowdump)$/i;
            
            oFReader.onload = function (oFREvent) {
                
                base64 = oFREvent.target.result;
                
                $("#" + options.destID).data('bg', base64);
                $("#" + options.destID).css('backgroundImage', "url(" + base64 + ")");
                
                if (options.server && options.autoUpload) {
                    self.upload();
                } else {
                    options.change && options.change(base64);
                }
            };
            
            var aFiles = $this.get(0).files;
            if (aFiles.length === 0) {
                return;
            }
            if (!rFilter.test(aFiles[0].type)) {
                alert("操作错误");
                return;
            }
            oFReader.readAsDataURL(aFiles[0]);
        }
        
        this.upload = function (callback) {
            
            if (!options.server) {
                alert('未配置上传服务器地址');
                return false;
            }
            
            options.startUpload && options.startUpload();
            
            return $.ajax({
                url: options.server,
                method: 'post',
                dataType: 'json',
                data: {base64: base64},
                success: function (ret) {
                    if (!ret) {
                        alert('网络错误');
                    }
                    if (ret.code == 1) {
                        options.finishUpload && options.finishUpload();
                        options.change && options.change(ret.path);
                        callback && callback(ret);
                    } else {
                        alert(ret.msg);
                    }
                },
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    alert('网络错误:' + textStatus);
                },
            }).catch((e) => {
            });
        };
    };
    
    $.fn.uploadImagePreview = function (options) {
        return new uploadImagePreview($(this), options);
    };
    
})(jQuery);